﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;
using AlgorithmResult;

namespace SegGen
{
    /// <summary>
    /// Population  A group of Genomes in the current Generation 
    /// </summary>
   public  class Population
    {

        Population m_NeighbourPopulation2 = null;
        public static event ProgressEventHandler ProgressHandler = null;
        public Population NeighbourPopulation2
        {
            get { return m_NeighbourPopulation2; }
            set { m_NeighbourPopulation2 = value; }
        }
        

       // the size of population is number individuals in this population
        protected int m_Population_Size;

        private Codon m_codon;

        protected Codon Codon
        {
            get { return m_codon; }
            set { m_codon = value; }
        }


        Population m_NeighbourPopulation = null;

        public Population NeighbourPopulation
        {
            get { return m_NeighbourPopulation; }
            set { m_NeighbourPopulation = value; }
        }

       
       
      

        public int Population_Size
        {
            get { return m_Population_Size; }
            set { m_Population_Size = value; }
        }
 
         /// <summary>
         ///  The list of individuals in population
         /// </summary>
        private List<Individual> m_Individuals_List = new List<Individual>();

        public List<Individual> Individuals_List
        {
            get { return m_Individuals_List; }
            set { m_Individuals_List = value; }
        }

      public void printAll()
      {
          Console.WriteLine("***************************************"+this.ToString()+"**************************************************************");
             foreach( Individual element in Individuals_List)
                       element.Print();

          Console.WriteLine("************************************************************************************************************************");
      }

      public virtual void Crossover() { }
      public virtual void calculateFitness(Population _population) { }
      

      public Population(int numNucleotidesInCodon)
      {
          m_codon = new Codon(numNucleotidesInCodon);
          m_Population_Size = 0;
      }



      /// <summary>
      ///  Function for mutation
      /// </summary>
      public virtual void Mutate() { }
        
       
       
 
        /// 
     

       /// <summary>
       /// Individuals are selected from this population in order to generate new individuals . 
       /// </summary>
       /// <param name="numTopIndividuals"></param>
       /// <returns></returns>
      public virtual void Selection(List<Individual> _Pt_List, List<Individual> _Pnot_List)
      {
          
      }



        public virtual Individual ExtractionOfSolution()
        {
            return null;
        }

        internal void UpdateExternalArchive(Population External_Archive_P)
        {
            throw new NotImplementedException();
        }

        internal void WriteNextGeneration(Population Current_Population_Pt)
        {
            throw new NotImplementedException();
        }

        internal void CreateRandomIndividuals(ref String gene, int numIndividuals, int numBoundariesInIndividual, int minSegmentSize,double alpha)
        {
            // init population size
            m_Population_Size = numIndividuals;
           // m_codon = new Codon(numNucleotidesInCodon);

            for (int i = 0; i < numIndividuals; i++)
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                
                // The input file contains triplets, every triplet size is 3
                Individual newIndividual = new Individual(ref gene, numBoundariesInIndividual, minSegmentSize, Codon.CodonNumNucleotides ,i,alpha);

              
                // add created individual into population
                m_Individuals_List.Add(newIndividual);
                if (ProgressHandler != null)
                {
                    ProgressHandler(this, new progressEvent(i+1, null));
                }

               // Console.WriteLine("create one individual Time: {0} ms", sw.ElapsedMilliseconds);
                sw.Stop();
            }
        }

         public void printPopulation()
         {
             int i = 1;
             foreach (Individual ind in m_Individuals_List)
             {
                 Console.WriteLine("Individual : " + i++);
                 ind.Print();
             }
         }


       /// <summary>
       /// 
       /// </summary>
         protected void calculateProbabilityOfSelection()
         {
                     // the sum of aggregations
                double sumF = 0;

                // go throw all individuals and sum aggregations
                for (int i = 0; i < Individuals_List.Count; i++ )
                {
                    sumF += Individuals_List.ElementAt(i).F;
                }

                // go throw all individuals and set probability of selection from 0 to 1
                for (int i = 0; i < Individuals_List.Count; i++)
                {
                    Individuals_List.ElementAt(i).ProbabilityOfSelection = (double)((double)(Individuals_List.ElementAt(i).Agg) / sumF);
                        // (double)((double)(Individuals_List.ElementAt(i).C + Individuals_List.ElementAt(i).D) / sumF) ;
                     //   (double)((double)(Individuals_List.ElementAt(i).F * 100) / sumF)/100;
                }

          
         }












         public virtual void Update(Population pop)
         {
             
         }
    }
}
